package com.gitee.wsl.common.ui.ext.color

import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.colorspace.connect
import com.gitee.wsl.mathematics.interpolator.Percent
import com.gitee.wsl.mathematics.interpolator.ext.toRatio
import com.gitee.wsl.mathematics.interpolator.pct

const val redMask = -0x1000000
const val greenMask = 0x00ff0000
const val blueMask = 0x0000ff00
const val alphaMask = 0x000000ff
const val rgbMask = 0xffffff00.toInt()


val Color.r get() = this.red.toInt()

val Color.g get() = this.green.toInt()

val Color.b get() = this.blue.toInt()

/**
 * Instantiate a color using its rgb Int value and alpha. Should be used with hexadecimal literal.
 * @sample: `Colors.rgb(0x0b0b0b, .5)`
 */
fun Color.Companion.rgb(rgb:Int, alpha: Percent = 100.pct): Color {
    val value= rgb and 0x00ffffff or ((alpha * 255.0f + 0.5f).toInt() shl 24)
    return Color(value)
}

fun Color.Companion.rgb(red: Int, green: Int, blue: Int, alpha: Float = 1f): Color = rgb(red,green,blue,Percent(alpha))

fun Color.Companion.rgb(red: Double, green: Double, blue: Double, alpha: Float = 1f): Color = rgb(red.toInt(),green.toInt(),blue.toInt(),Percent(alpha))

/**
 * Instantiate a color using its r,g,b Int values and alpha
 * @sample: `Colors.rgb(128, 128, 128, .5)`
 */
fun Color.Companion.rgb(red: Int, green: Int, blue: Int, alpha: Percent): Color {
    val rgb = (red.coerceIn(0, 255) shl 16) + (green.coerceIn(0, 255) shl 8) + blue.coerceIn(0, 255)
    return rgb(rgb, alpha)
}


fun Color.toBgr(): Int {
    val colorSpace = colorSpace
    val color = floatArrayOf(red, green, blue)

    // The transformation saturates the output
    colorSpace.connect().transform(color)

    return ((color[2] * 255.0f + 0.5f).toInt() shl 16) or
            ((color[1] * 255.0f + 0.5f).toInt() shl 8) or
            (color[0] * 255.0f + 0.5f).toInt()
}

// Modified version of toArgb
 fun Color.toAbgr(): Int {
    val colorSpace = colorSpace
    val color = floatArrayOf(red, green, blue, alpha)

    // The transformation saturates the output
    colorSpace.connect().transform(color)

    return (color[3] * 255.0f + 0.5f).toInt() shl 24 or
            ((color[2] * 255.0f + 0.5f).toInt() shl 16) or
            ((color[1] * 255.0f + 0.5f).toInt() shl 8) or
            (color[0] * 255.0f + 0.5f).toInt()
}

// For some reason, passing 0 (fully transparent black) to the setAccentPolicy with
// transparent accent policy results in solid red color. As a workaround, we pass
// fully transparent white which has the same visual effect.
 fun Color.toAbgrForTransparent() = if (alpha == 0F) 0x00FFFFFF else toAbgr()